#include "NXmlParseMaster.h"
#include "NXmlParseHelper.h"
#include "NGameException.h"

#include "NeroCore\NMemoryManager.h"

#pragma comment(lib,"tinyxml.lib")

using namespace NXML;

NXmlParseMaster* NXmlParseMaster::sInstance = NULL;

NXmlParseMaster::NXmlParseMaster(void)
{
	//
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlIfHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlLoadHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlWorldHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlSectorHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlEntityHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlAttribueHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlTableHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlComponentHelper(this);
	MY_NEW(Memory::HID_Engine,"XmlHelper") NXML::NXmlDirectorHelper(this);
}

NXmlParseMaster::~NXmlParseMaster(void)
{
	std::list<NXmlParseHelper*>::iterator _it = mHealpers.begin();
	for(; _it != mHealpers.end(); _it++)
	{
		MY_DELETE((*_it));
	}
	mHealpers.clear();
}

void NXmlParseMaster::Initialize()
{
	if(sInstance == NULL)
	{
		sInstance = MY_NEW(Memory::HID_Engine,"XmlParseMaster") NXmlParseMaster();
	}
}

void NXmlParseMaster::Deinitialize()
{
	if(sInstance != NULL)
	{
		MY_DELETE(sInstance);
		sInstance = NULL;
	}
}

NXmlParseMaster* NXmlParseMaster::GetInstance()
{
	return sInstance;
}

void NXmlParseMaster::AddHelper(NXmlParseHelper * aHelper)
{
	mHealpers.push_back(aHelper);
}

void NXmlParseMaster::RemoveHelper(NXmlParseHelper * aHelper)
{
	mHealpers.remove(aHelper);
}

void NXmlParseMaster::ParseXMl(const char* file)
{
	Memory::MemoryManager::GetInstance()->Disable();

	BeginParse(file);

	Memory::MemoryManager::GetInstance()->Enable();
}

NXmlParseMaster::NXmlSharedData * NXmlParseMaster::GetSharedData()
{
	return &mSharedData;
}

void NXmlParseMaster::StartElementParse(TiXmlElement* element)
{
	NXmlParseHelper* currentHelper = NULL;
	while (element)
	{
		//Pass element to all helpers
		std::list<NXmlParseHelper*>::iterator _it = mHealpers.begin();
		for(; _it != mHealpers.end(); _it++)
		{
			if((*_it)->StartElementHandler(element))
			{
				currentHelper = (*_it);
				break;
			}
		}

		//Handle child nodes
		if(element->FirstChild() && !mSharedData.SkipContainedData)
		{
			StartElementParse(element->FirstChildElement());
		}

		mSharedData.SkipContainedData = false;
		//Handle end of element
		if(currentHelper != NULL)
		{
			currentHelper->EndElementHandler(element);
		}
		element = element->NextSiblingElement();
	}
}

void NXmlParseMaster::BeginParse(const char* file)
{
	TiXmlDocument xmlDoc(file);
	if (!xmlDoc.LoadFile())
	{
		//throw Game::NGameException("NXmlParseMaseter:BeginParse - Failed to load file");
		return;
	}

	TiXmlHandle xmlHandle(&xmlDoc);
	TiXmlElement* element;
	TiXmlHandle rootHandle(0);

	element = xmlHandle.FirstChildElement().Element();
	rootHandle = TiXmlHandle(element);
	StartElementParse(element);
}